


//para usar qDebug()
#include <QtGui>

//para testes
#include "ohlcvset.h"
#include "stockfileparser.h"
#include "candelabrodb.h"
#include "testes.h"

bool showSucceededTests = false;

void assertEquals( int obtained, int expected, int testId ) {
    if (expected != obtained)
        qDebug()  << "Test "<< testId <<" failed: ["<<obtained <<"] was obtained but [" << expected <<"] was expected.";
    else if(showSucceededTests)
        qDebug() << "Test "<< testId <<" run OK";
}

void assertTrue( bool obtained, int testId ) {
    if (!obtained)
        qDebug()  << "Test "<< testId <<" failed: ["<< obtained <<"] was obtained but [" << !obtained <<"] was expected.";
    else if(showSucceededTests)
        qDebug() << "Test "<< testId <<" run OK";
}

void assertFalse( bool obtained, int testId){
    assertTrue(!obtained, testId);
}



/*
 * Testa a ordenacao do vetor de OHLCVs. Os elementos sao
 * ordenados pela data, que eh uma data no formato unix.
 *
 */
void testeOrdenacaoOHLCVSet()
{
    OHLCVSet cjto;

    OHLCVItem aux1 = OHLCVItem(new QString("A"), 1.0, 1.0, 1.0, 1.0, 1.0, 1);
    OHLCVItem aux2 = OHLCVItem(new QString("A"), 1.0, 1.0, 1.0, 1.0, 1.0, 2);
    OHLCVItem aux3 = OHLCVItem(new QString("A"), 1.0, 1.0, 1.0, 1.0, 1.0, 3);
    OHLCVItem aux4 = OHLCVItem(new QString("A"), 1.0, 1.0, 1.0, 1.0, 1.0, 4);
    OHLCVItem aux5 = OHLCVItem(new QString("A"), 1.0, 1.0, 1.0, 1.0, 1.0, 5);

    cjto.append(aux5);
    cjto.append(aux1);
    cjto.append(aux3);
    cjto.append(aux2);
    cjto.append(aux4);

    qSort(cjto);

    assertEquals(cjto.at(0).unixdate, 1, 101);
    assertEquals(cjto.at(1).unixdate, 2, 101);
    assertEquals(cjto.at(2).unixdate, 3, 103);
    assertEquals(cjto.at(3).unixdate, 4, 104);
    assertEquals(cjto.at(4).unixdate, 5, 105);

    return;
}


void testeOrdenacaoMultiplosStocksOHLCVSet()
{
    OHLCVSet cjto;

    OHLCVItem aux1 = OHLCVItem(new QString("D"), 1.0, 1.0, 1.0, 1.0, 1.0, 1);
    OHLCVItem aux2 = OHLCVItem(new QString("C"), 1.0, 1.0, 1.0, 1.0, 1.0, 2);
    OHLCVItem aux3 = OHLCVItem(new QString("E"), 1.0, 1.0, 1.0, 1.0, 1.0, 3);
    OHLCVItem aux4 = OHLCVItem(new QString("A"), 1.0, 1.0, 1.0, 1.0, 1.0, 4);
    OHLCVItem aux5 = OHLCVItem(new QString("B"), 1.0, 1.0, 1.0, 1.0, 1.0, 5);

    cjto.append(aux5);
    cjto.append(aux1);
    cjto.append(aux3);
    cjto.append(aux2);
    cjto.append(aux4);

    qSort(cjto);

    assertEquals(cjto.at(0).unixdate, 4, 201);
    assertEquals(cjto.at(1).unixdate, 5, 202);
    assertEquals(cjto.at(2).unixdate, 2, 203);
    assertEquals(cjto.at(3).unixdate, 1, 204);
    assertEquals(cjto.at(4).unixdate, 3, 205);

    return;
}



void testeCriacaoDatabase(){
    CandelabroDB db;

    //apagando anterior
//    db.deleteDatabase();
//    assertFalse(db.databaseExists(), 401);
//    assertFalse(db.isDatabaseOpen(), 402);
//    //criando e abrindo atual
//    db.openDatabase();
//    assertTrue(db.databaseExists(), 403);
//    assertTrue(db.openDatabase(), 420);
//    assertTrue(db.isDatabaseOpen(), 404);
//    assertFalse(db.isDatabaseSetup(), 405);

    //configurando banco atual
    db.deleteDatabase();
    db.openDatabase();
//    db.isDatabaseSetup();
    db.setUpDatabase();
//    assertFalse(db.isDatabaseSetup(), 422);
//    assertTrue(db.setUpDatabase(), 421);
//    assertTrue(db.databaseExists(), 406);
//    assertTrue(db.isDatabaseOpen(), 407);
//    assertTrue(db.isDatabaseSetup(), 408);

//    assertTrue(db.closeDatabase(), 409);
}

void testeIgualdadeOHLCVItem(){
    OHLCVItem aux1 = OHLCVItem(new QString("a"), 1.0, 1.0, 1.0, 1.0, 1.0, 1);
    OHLCVItem aux2 = OHLCVItem(new QString("b"), 1.0, 1.0, 1.0, 1.0, 1.0, 1);

    assertFalse(aux1==aux2, 501);
    aux2 = OHLCVItem(new QString("a"), 2.0, 1.0, 1.0, 1.0, 1.0, 1);
    assertFalse(aux1==aux2, 502);
    aux2 = OHLCVItem(new QString("a"), 1.0, 2.0, 1.0, 1.0, 1.0, 1);
    assertFalse(aux1==aux2,503);
    aux2 = OHLCVItem(new QString("a"), 1.0, 1.0, 2.0, 1.0, 1.0, 1);
    assertFalse(aux1==aux2, 504);
    aux2 = OHLCVItem(new QString("a"), 1.0, 1.0, 1.0, 2.0, 1.0, 1);
    assertFalse(aux1==aux2, 505);
    aux2 = OHLCVItem(new QString("a"), 1.0, 1.0, 1.0, 1.0, 2.0, 1);
    assertFalse(aux1==aux2, 506);
    aux2 = OHLCVItem(new QString("a"), 1.0, 1.0, 1.0, 1.0, 1.0, 2);
    assertFalse(aux1==aux2, 507);
    aux2 = OHLCVItem(new QString("a"), 1.0, 1.0, 1.0, 1.0, 1.0, 1);
    assertTrue(aux1==aux2, 508);
}

void testeImportacaoDatabase(){
    CandelabroDB db;
    db.openDatabase();
    db.setUpDatabase();

    QTime total;

    StockFileParser parser;

    //arquivos
    QStringList arquivos;
    arquivos << "bbdc4.sa" << "bvmf3.sa" << "ciel3.sa" << "csna3.sa"
             << "ecod3.sa" << "fnor11.sa" << "gfsa3.sa" << "ggbr4.sa"
             << "itsa4.sa" << "itub4.sa" << "jbss3.sa" << "milk11.sa"
             << "ogxp3.sa" << "pdgr3.sa" << "petr3.sa" << "petr4.sa"
             << "rdcd3.sa" << "rpmg3.sa" << "tcsl4.sa" << "telb3.sa"
             << "telb4.sa" << "unip6.sa" << "usim5.sa" << "vale3.sa"
             << "vale5.sa";

//    int ids[] = {140 , 132 , 240 , 864 , 334 , 430 , 448 , 459 , 543 , 547 , 555 , 580 , 714 , 746 , 752 , 753 , 800 , 750 , 960 , 930 , 931 , 992 , 997 , 1003 , 1004};
    //total de linhas = total de acoes - 1
//    int tamanhos[] = {2807, 758, 338, 2010, 969, 1962, 1815, 2010, 2813, 2807, 884,
//                      737, 1012, 1110, 2793, 2793, 813, 2556, 1337, 2010, 2010, 2010,
//                      2793, 2777, 2010};

    //vetor de conjunto
    OHLCVSet cjtos[arquivos.size()];

    int teste = 800;

    //comparando ids selecionados
//    total.restart();
//    for (int i=0;i<arquivos.size();i++){
//        assertEquals(db.stockId(arquivos.at(i)), ids[i], ++teste);
//    }
//    qDebug("Time elapsed comparing ids: %.2f", total.elapsed()*1.0/1000);


    //lendo arquivo e comparando tamanhos
    total.restart();
    for (int i=0;i<arquivos.size();i++){
        const OHLCVSet tmp = parser.getSingleStockSet("./resources/"+arquivos.at(i)+".csv", arquivos.at(i).toUpper() );
        cjtos[i] = tmp;
//        assertEquals(cjtos[i].size(), tamanhos[i]-1 , teste++);
    }
    qDebug("Time elapsed parsing files: %.2f seconds", total.elapsed()*1.0/1000);


    teste = 901;


    //importando
    total.restart();
    for (int i=0;i<arquivos.size();i++){
        QTime local;
        local.start();
        assertTrue(db.insertStockPrice(cjtos[i]), teste++);
        qDebug("File imported in %.2f seconds", local.elapsed()*1.0/1000);

    }
    qDebug("Time elapsed importing files: %.2f seconds", total.elapsed()*1.0/1000);

}


void testeDeletarSets()
{
    CandelabroDB db;
    db.openDatabase();
    db.setUpDatabase();

    QTime total;

    StockFileParser parser;

    //arquivos
    QStringList arquivos;
    arquivos << "bbdc4.sa" << "bvmf3.sa" << "ciel3.sa" << "csna3.sa"
             << "ecod3.sa" << "fnor11.sa" << "gfsa3.sa" << "ggbr4.sa"
             << "itsa4.sa" << "itub4.sa" << "jbss3.sa" << "milk11.sa"
             << "ogxp3.sa" << "pdgr3.sa" << "petr3.sa" << "petr4.sa"
             << "rdcd3.sa" << "rpmg3.sa" << "tcsl4.sa" << "telb3.sa"
             << "telb4.sa" << "unip6.sa" << "usim5.sa" << "vale3.sa"
             << "vale5.sa";

    //total de linhas = total de acoes - 1
    int tamanhos[] = {2807, 758, 338, 2010, 969, 1962, 1815, 2010, 2813, 2807, 884,
                      737, 1012, 1110, 2793, 2793, 813, 2556, 1337, 2010, 2010, 2010,
                      2793, 2777, 2010};

    //vetor de conjunto
    OHLCVSet cjtos[arquivos.size()];


    int teste = 2000;
    //lendo arquivo e comparando tamanhos
    total.restart();
    for (int i=0;i<arquivos.size();i++){
        const OHLCVSet tmp = parser.getSingleStockSet("../resources/"+arquivos.at(i)+".csv", arquivos.at(i).toUpper() );
        cjtos[i] = tmp;
        assertEquals(cjtos[i].size(), tamanhos[i]-1 , teste++);
    }
    qDebug("Time elapsed parsing files: %.2f seconds", total.elapsed()*1.0/1000);


    teste = 2100;


    //importando
    total.restart();
    for (int i=0;i<arquivos.size();i++){
        QTime local;
        local.start();
        assertTrue(db.deleteSet(cjtos[i]), teste++);
        qDebug("Set deleted in %.2f seconds", local.elapsed()*1.0/1000);
    }
    qDebug("Time elapsed deleting set: %.2f seconds", total.elapsed()*1.0/1000);
}


void testeImportacaoSimples(){
    //database operations
    CandelabroDB db;
    db.deleteDatabase();
    db.openDatabase();
    db.setUpDatabase();

    OHLCVItem aux1 = OHLCVItem(new QString("a"), 1.0, 1.0, 1.0, 1.0, 1.0, 1);
    OHLCVItem aux2 = OHLCVItem(new QString("a"), 1.0, 1.0, 1.0, 1.0, 1.0, 2);
    OHLCVItem aux3 = OHLCVItem(new QString("a"), 1.0, 1.0, 1.0, 1.0, 1.0, 3);


    assertFalse(db.existsPrice("a", 1),601);
    assertFalse(db.existsPrice("a", 2),602);
    assertFalse(db.existsPrice("a", 3),603);

    assertTrue(db.insertStockPrice(aux1),604);
    assertTrue(db.existsPrice("a", 1),605);
    assertFalse(db.existsPrice("a", 2),606);
    assertFalse(db.existsPrice("a", 3),607);

    assertTrue(db.insertStockPrice(aux2),608);
    assertTrue(db.existsPrice("a", 1),609);
    assertTrue(db.existsPrice("a", 2),610);
    assertFalse(db.existsPrice("a", 3),611);

    assertTrue(db.insertStockPrice(aux3),612);
    assertTrue(db.existsPrice("a", 1),613);
    assertTrue(db.existsPrice("a", 2),614);
    assertTrue(db.existsPrice("a", 3),615);


    //selecionando os inseridos
    OHLCVSet set = db.selectAll("a");
    assertTrue(set.at(0)==aux1, 616);
    assertTrue(set.at(1)==aux2, 617);
    assertTrue(set.at(2)==aux3, 618);

    assertTrue(db.existsPrice("a", 1),619);


    //fechando
    assertTrue(db.closeDatabase(), 620);

}



void testeInserirDescricoesStocks(){
    CandelabroDB db;
    db.deleteDatabase();
    db.openDatabase();
    db.setUpDatabase();

    int testes = 1000;
    QStringList lista = ativos_desc.split(",");

    QTime total;
    total.start();
//    olha o i+=2
//    for (int i=0; i<lista.size();i+=2){
//        assertFalse(db.existsStock(lista.at(i)),++testes);
//    }
//    qDebug("Time elapsed checking stocks: %.2f", total.elapsed()*1.0/1000);


    for (int i=0; i<lista.size();i+=2){
        // o primeiro eh o ativo, o segundo sua descricao
//        assertTrue(db.insertStock(lista.at(i), lista.at((i+1))),++testes);
        db.insertStock(lista.at(i), lista.at((i+1)));
    }
//    qDebug("Time elapsed importing stocks: %.2f", total.elapsed()*1.0/1000);


//    total.restart();
//    for (int i=0; i<lista.size();i+=2){
//        assertTrue(db.existsStock(lista.at(i)),++testes);
//    }
//    qDebug("Time elapsed checking stocks: %.2f seconds", total.elapsed()*1.0/1000);

}




void testeMostrarAcoesComPrecos(){
    CandelabroDB db;
    db.openDatabase();

    QStringList lista;
    lista << "BBDC4.SA" << "BVMF3.SA" << "CIEL3.SA" << "CSNA3.SA" << "ECOD3.SA" << "FNOR11.SA" <<
             "GFSA3.SA" << "GGBR4.SA" << "ITSA4.SA" << "ITUB4.SA" << "JBSS3.SA" << "MILK11.SA" <<
             "OGXP3.SA" << "PDGR3.SA" << "PETR3.SA" << "PETR4.SA" << "RDCD3.SA" << "RPMG3.SA" <<
             "TCSL4.SA" << "TELB3.SA" << "TELB4.SA" << "UNIP6.SA" << "USIM5.SA" << "VALE3.SA" <<
             "VALE5.SA" ;


    QStringList lista2 = db.getPricedStocksNames();

    for (int i=0;i<lista.count(); i++){
        assertTrue(lista.at(i)==lista2.at(i), i);
    }


}



void testeRetornarStocksData()
{

    CandelabroDB db;
    db.openDatabase();


    QDate inicio = QDateTime::fromTime_t(946864800).date();
    QDate fim    = QDate::currentDate();
    OHLCVSet set = db.getStockPrices("BVMF3.SA", inicio, fim);


}


void refazerBanco()
{

    CandelabroDB db;
    db.deleteDatabase();
    db.openDatabase();
    db.setUpDatabase();

    testeInserirDescricoesStocks();
    testeImportacaoDatabase();


}

//int main(int argc, char *argv[])
//{
//////    testeOrdenacaoOHLCVSet();
//////    testeOrdenacaoMultiplosStocksOHLCVSet();
//////    testeCriacaoDatabase();
//////    testeIgualdadeOHLCVItem();
////    testeImportacaoSimples();

////    testeInserirDescricoesStocks();
//////    testeDeletarSets();
////    testeImportacaoDatabase();

////    testeMostrarAcoesComPrecos();

////    testeRetornarStocksData();

//    refazerBanco();

//    //apenas para nao mostrar warnings, isso eh uma gambiarra
////    argc = 1;
////    *argv=0 ;
//    return 0;
//        refazerBanco();
//}
